package ms.unicorn.palette;

import java.util.Collections;
import java.util.Map;

import ms.unicorn.diagram.part.UnicornDiagramEditorPlugin;
import ms.unicorn.modellanguage.ElementType;
import ms.unicorn.modellanguage.HintedSpecializationType;
import ms.unicorn.modellanguage.IModelLanguage;
import ms.unicorn.modellanguage.LanguageElement;
import ms.unicorn.modellanguage.LanguageEntity;
import ms.unicorn.modellanguage.LanguageRegistry;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.gef.palette.PaletteEntry;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.jface.resource.ImageDescriptor;

public class PaletteTool extends PaletteItem {
	private String hint, label, tooltip, language, typeId;
	private ImageDescriptor smallImage, largeImage;
	
	public void setSmallImage(ImageDescriptor smallImage) {
		this.smallImage = smallImage;
	}

	public static void createToolFromConfigItem(
			IConfigurationElement child, PaletteGroup group,
			Map<String, PaletteItem> itemMap) throws Exception {

		String id = child.getAttribute("id");
		Object toolObject = id != null ? itemMap.get(id) : null;
		PaletteTool tool = null;
		if (toolObject == null) {
			tool = new PaletteTool();
			if (id != null && id.length() > 0)
				itemMap.put(id, tool);
			tool.setId(id);
			group.getTools().add(tool);
		} else if (toolObject instanceof PaletteTool)
			tool = (PaletteTool) toolObject;
		else
			throw new Exception("The tool id " + id
					+ " has beed used as a group, not a tool entry.");

		tool.setLabel(child.getAttribute("label"));
		tool.setLanguage(child.getAttribute("language"));
		tool.setTypeId(child.getAttribute("typeId"));
		
		for (String name : child.getAttributeNames())
			if (name.equalsIgnoreCase("tooltip"))
				tool.setTooltip(child.getAttribute(name));
			else if (name.equalsIgnoreCase("toolSemantic"))
				tool.setHint(child.getAttribute(name));
			else if (name.equalsIgnoreCase("smallImage")) {
				String image = child.getAttribute(name);
				String pluginId = child.getDeclaringExtension()
						.getUniqueIdentifier();
				ImageDescriptor imageDescriptor = UnicornDiagramEditorPlugin
						.imageDescriptorFromPlugin(pluginId, image);
				tool.setSmallImage(imageDescriptor);
			} else if (name.equalsIgnoreCase("largeImage")) {
				String image = child.getAttribute(name);
				String pluginId = child.getDeclaringExtension()
						.getUniqueIdentifier();
				ImageDescriptor imageDescriptor = UnicornDiagramEditorPlugin
						.imageDescriptorFromPlugin(pluginId, image);
				tool.setLargeImage(imageDescriptor);
			}
	}

	public PaletteEntry createPaletteEntry() {
		IModelLanguage lang = LanguageRegistry.INSTANCE.getLanguage(getLanguage());
		ToolEntry entry = null;
		if (lang != null) {
			LanguageElement e = lang.getElement(typeId);
			if (e !=  null) {
				if (e instanceof LanguageEntity)
					entry = createEntityEntry(e);
				else
					entry = createRelationEntry(e);
				if (e.getElementType() instanceof HintedSpecializationType) {
					HintedSpecializationType eType = (HintedSpecializationType) e.getElementType();
					eType.setLanguage(lang);
					eType.setSemanticHint(this.hint);
				}
			}
			if (entry != null) {
				entry.setToolProperty("language", lang);
				entry.setToolProperty("typeId", this.typeId);
				entry.setToolProperty("semanticHint", this.hint);
			}
		}
		return entry;
	}

	private ToolEntry createRelationEntry(LanguageElement e) {
		IElementType type = e.getElementType();
		ToolEntry result = new LinkToolEntry(label, getTooltip(),
				getSmallImage(), getLargeImage(), getHint(), Collections.singletonList(type));
		return result;
	}

	private ToolEntry createEntityEntry(LanguageElement e) {
		IElementType type = e.getElementType();
		ToolEntry result = new NodeToolEntry(label, getTooltip(),
				getSmallImage(), getLargeImage(), getHint(), Collections.singletonList(type));
		return result;
	}

	public ImageDescriptor getSmallImage() {
		return smallImage;
	}

	public void setLargeImage(ImageDescriptor largeImage) {
		this.largeImage = largeImage;
	}

	public ImageDescriptor getLargeImage() {
		return largeImage != null ? largeImage : smallImage;
	}

	public void setHint(String hint) {
		this.hint = hint;
	}

	public String getHint() {
		return hint;
	}

	public void setLabel(String label) {
		this.label = label;
	}

	public String getLabel() {
		return label;
	}

	public void setTooltip(String tooltip) {
		this.tooltip = tooltip;
	}

	public String getTooltip() {
		return tooltip != null ? tooltip : label;
	}

	public void setLanguage(String language) {
		this.language = language;
	}

	public String getLanguage() {
		return language;
	}

	public void setTypeId(String typeId) {
		this.typeId = typeId;
	}

	public String getTypeId() {
		return typeId;
	}
}